home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gekkan Dennou Club 140
/
Gekkan Dennou Club - 2000.1 Vol. 140 (Japan).7z
/
Gekkan Dennou Club - 2000.1 Vol. 140 (Japan) (Track 1).bin
/
games
/
km21
/
src
/
mainsys.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-12-05
|
31KB
|
1,692 lines
/*sys?
mainsys
by 電魔団\shoryu 1998,99
*/
#include <stdio.h>
#include <stdlib.h>
#include <mouse.h>
#include <iocslib.h>
#include <doslib.h>
#include <math.h>
#include <graph.h>
#include <mouse.h>
#include <string.h>
#include <zmusic.h>
#include "STRUCTS.INC"
DEVICE Dev,oDev,sDev; //入力情報
TASK nTask; //ワーククリア用空ダミータスク
ESTASK nesTask; // Human Xファイルはこの領域を0クリアしてから動く
PSTASK npsTask; //
TASK PTask[2]; //プレーヤー
TASK MTask[MAX_MTASK]; //管理タスク(ステージ管理/編隊等)
TASK ETask[MAX_ETASK]; //敵
TASK ITask[MAX_ITASK]; //アイテム・演出物
ESTASK ESTask[MAX_ESTASK]; //敵弾
PSTASK PSTask[MAX_PSTASK]; //自機弾
int scoreHI; //ハイスコア
int score1P; //得点 @@いま、1Pオンリー
int left1P; //残機
int vwait; //V-Sync待ち(0=する/1=しない)
int shtmod; //隠しシューティングモード???
int bigmod; //隠し巨大モード???
int sortFlag=0; //キャラクタソート1=する/0=しない
int dipSwitch; //ディップスイップ
//------------------------------ゲーム固有
// 外部
#include "stepman.inc"
int gameStep=STEP_INIT_ALL;
int gameLevel;
int gameTotalCounter=0;
int SyncMan__dispPage=0;
extern int StepMan();
int main(argc,argv)
int argc;
char *argv[];
{
int ssp;
InitAllUser(argc,argv);
ssp=B_SUPER(0);
InitAllSuper(argc,argv);
while( gameStep!=STEP_EXIT ){
DevMan();
StepMan(); if( gameStep==STEP_EXIT ){ break; }
TaskMan(); if( gameStep==STEP_EXIT ){ break; }
// HitchkMan0();
if( sortFlag==1 ){ SyncManY(); }
else{ SyncMan(); }
// /**/if( Dev.kb[0x0e]&0x01 )getch();
}
TermSuper();
B_SUPER(ssp);
TermUser();
exit(0);
}
int InitAllUser(argc,argv)
int argc;
char *argv[];
{
{
int ac;
for( ac=1; ac<argc; ac++ ){ ;
if( argv[ac][0]=='-' || argv[ac][0]=='/' ){ ;
switch( argv[ac][1] ){
case 'v': case 'V':
vwait=1;
break;
case 's': case 'S':
sortFlag=0;
break;
case 't': case 'T':
shtmod=1;
break;
case 'd': case 'D':
sscanf(&argv[ac][2],"%x",&dipSwitch);
break;
}}}
}
screen(1,3,1,1);
OS_CUROF();
cls();
// system("pic km21back.pic");
CRTMOD(270);
// HOME(0,0,256);
apic_load("km21back.pic",0,0);
// HOME(0,0,0);
APAGE(0x0f);
// screen(0,1,1,1); //16,256,4
sp_init();
TNUM__Init();
spfile_def("KM21.SP",0x00); //スプライト読み込み
palfile_def("KM21.PAL",0x01);
sp_disp(1);
sp_on(0,127);
v_priority("TSG","0123");
mouse(4);mouse(2);
SOUND_CALL(0);
AllTaskFree();
}
int InitAllSuper(argc,argv)
int argc;
char *argv[];
{
extern int TNUM__Init(),TNUM__Print();
{ //画面上半分を下半分にコピー
unsigned short *s,*d;
s=0xC00000;
d=0xC40000;
while( s<0xC40000 ){
*d++=*s++;
}
}
{
short *vctrl_r2=0xe8260;
*vctrl_r2|=0x1f;
}
/*
{
unsigned short *vram,mask=0xfffe;
for( vram=0xc00000; vram<0xc80000; vram++ ){
*vram&=mask;
}
}
*/
}
int TermSuper()
{
short *vram,z=0;
for( vram=0xe00000; vram<0xe80000; vram++ ){
*vram=z;
}
}
int TermUser()
{
SOUND_CALL(0x800);
mouse(0);
OS_CURON();
KFLUSHIO(0xff);
screen(2,0,1,1);
}
//----------------------------------------------------------------------- DevMan()
int DevMan()
{
int kg,b,kb;
oDev=Dev; //入力更新
//キーボード
for( kg=0;kg<=0x0f;kg++ ){
Dev.kb[kg]=BITSNS(kg);
sDev.kb[kg]=0;
for( b=0;b<8;b++ ){
kb=1<<b;
if( !(oDev.kb[kg]&kb) && (Dev.kb[kg]&kb) ){
sDev.kb[kg]|=kb;
}
}
}
//マウス
msstat(&(Dev.mdx),&(Dev.mdy),&(Dev.mbl),&(Dev.mbr));
mspos(&(Dev.mx),&(Dev.my));
sDev.mbl=( oDev.mbl!=-1 && Dev.mbl==-1 )?-1:0;
sDev.mbr=( oDev.mbr!=-1 && Dev.mbr==-1 )?-1:0;
//ジョイスティック
Dev.stick=stick(1);
Dev.strigA=(strig(1)&0x01);
Dev.strigB=(strig(1)&0x02);
sDev.strigA=( oDev.strigA==0 && Dev.strigA==1 )?1:0;
sDev.strigB=( oDev.strigB==0 && Dev.strigB==1 )?1:0;
//@@いんちきキースティック
#if 0
if( Dev.kb[0x08]&0x08 ){ Dev.stick=7; }
if( Dev.kb[0x08]&0x10 ){ Dev.stick=8; }
if( Dev.kb[0x08]&0x20 ){ Dev.stick=9; }
if( Dev.kb[0x08]&0x80 ){ Dev.stick=4; }
if( Dev.kb[0x09]&0x02 ){ Dev.stick=6; }
if( Dev.kb[0x09]&0x08 ){ Dev.stick=1; }
if( Dev.kb[0x09]&0x10 ){ Dev.stick=2; }
if( Dev.kb[0x09]&0x20 ){ Dev.stick=3; }
if( Dev.kb[0x0A]&0x20 ){ Dev.strig=1; }
#endif
}
int voffWait()
{
volatile unsigned char *gpip=0xe88001;
while((*gpip&0x10));
}
int vonWait()
{
volatile unsigned char *gpip=0xe88001;
while(!(*gpip&0x10));
}
//----------------------------------------------------------------------SyncMan()
#define X6sp_set(pl,x,y,n,p) \
X6sync_buf[(pl)*4+0]=(x); \
X6sync_buf[(pl)*4+1]=(y); \
X6sync_buf[(pl)*4+2]=(n); \
X6sync_buf[(pl)*4+3]=(p)
short X6sync_buf[128*4];
int SyncMan()
{
static FIX32 cnt=0;
short d,sppl;
d=(SyncMan__dispPage==0)?256:0;
{//スプライト
short tn,sn,an,px,py,pat;
TASK *t; //通常タスク
ESTASK *e; //敵弾
PSTASK *m; //
SPINFO *s;
sppl=0;
//プレイヤー
for( tn=0;tn<=1;tn++ ){
t=&PTask[tn];
if( t->func_addr==NULL ){ continue; }
// if( t->delay_timer>0 ){ continue; }
s=t->disp0_addr;
if( s==NULL ){ continue; }
//以下、表示
an=t->disp0_anim;
px=*(short *)&(t->disp0_x);
py=*(short *)&(t->disp0_y);
for( sn=0;sn<s->anim_info[t->disp0_anim]->chips;sn++ ){
px+=s->anim_info[t->disp0_anim]->splink[sn].ox;
py+=s->anim_info[t->disp0_anim]->splink[sn].oy;
pat=s->anim_info[t->disp0_anim]->splink[sn].patnum;
if( t->disp0_palet!=0 ){
pat&=0xf0ff;
pat=pat|(t->disp0_palet<<8);
}
X6sp_set(sppl,px,py,pat,3);
sppl++;
}
}
//敵機
for( tn=0;tn<MAX_ETASK;tn++ ){
t=&ETask[tn];
if( t->func_addr==NULL ){ continue; }
// if( t->delay_timer>0 ){ continue; }
s=t->disp0_addr;
if( s==NULL ){ continue; }
//以下、表示
an=t->disp0_anim;
px=*(short *)&(t->disp0_x);
py=*(short *)&(t->disp0_y);
for( sn=0;sn<s->anim_info[t->disp0_anim]->chips;sn++ ){
px+=s->anim_info[t->disp0_anim]->splink[sn].ox;
py+=s->anim_info[t->disp0_anim]->splink[sn].oy;
pat=s->anim_info[t->disp0_anim]->splink[sn].patnum;
if( t->disp0_palet!=0 ){
pat&=0xf0ff;
pat=pat|(t->disp0_palet<<8);
}
X6sp_set(
sppl, //実際に描画されるSPプレーン
px,
py,
pat,
3
);
sppl++;
}
}
//アイテム等
for( tn=0;tn<MAX_ITASK;tn++ ){
t=&ITask[tn];
if( t->func_addr==NULL ){ continue; }
// if( t->delay_timer>0 ){ continue; }
s=t->disp0_addr;
if( s==NULL ){ continue; }
//以下、表示
an=t->disp0_anim;
px=*(short *)&(t->disp0_x);
py=*(short *)&(t->disp0_y);
for( sn=0;sn<s->anim_info[t->disp0_anim]->chips;sn++ ){
px+=s->anim_info[t->disp0_anim]->splink[sn].ox;
py+=s->anim_info[t->disp0_anim]->splink[sn].oy;
pat=s->anim_info[t->disp0_anim]->splink[sn].patnum;
if( t->disp0_palet!=0 ){
pat&=0xf0ff;
pat=pat|(t->disp0_palet<<8);
}
X6sp_set(sppl,px,py,pat,3);
sppl++;
}
}
//敵弾用(1チップ限定)
for( tn=0;tn<MAX_ESTASK;tn++ ){
e=&ESTask[tn];
if( e->func_addr==NULL ){ continue; }
// if( e->delay_timer>0 ){ continue; }
s=e->disp0_addr;
if( s==NULL ){ continue; }
//以下、表示
an=e->disp0_anim;
px=*(short *)&(e->disp0_x);
py=*(short *)&(e->disp0_y);
sn=0;
px+=s->anim_info[e->disp0_anim]->splink[sn].ox;
py+=s->anim_info[e->disp0_anim]->splink[sn].oy;
pat=s->anim_info[t->disp0_anim]->splink[sn].patnum;
if( t->disp0_palet!=0 ){
pat&=0xf0ff;
pat=pat|(t->disp0_palet<<8);
}
X6sp_set(sppl,px,py,pat,3);
sppl++;
}
//自機用(1チップ限定)
for( tn=0;tn<MAX_PSTASK;tn++ ){
m=&PSTask[tn];
if( m->func_addr==NULL ){ continue; }
// if( m->delay_timer>0 ){ continue; }
s=m->disp0_addr;
if( s==NULL ){ continue; }
//以下、表示
an=m->disp0_anim;
px=*(short *)&(m->disp0_x);
py=*(short *)&(m->disp0_y);
sn=0;
px+=s->anim_info[an]->splink[sn].ox;
py+=s->anim_info[an]->splink[sn].oy;
pat=s->anim_info[an]->splink[sn].patnum;
if( t->disp0_palet!=0 ){
pat&=0xf0ff;
pat=pat|(t->disp0_palet<<8);
}
X6sp_set(sppl,px,py,pat,3);
sppl++;
}
}
if( vwait==0 ){ voffWait(); }
//スクロール
{
int pn;
unsigned short *spscr=0xEB0000,
*sync=X6sync_buf;
//cls();printf("%d",sppl);
for( pn=0;pn<min(sppl,128);pn++ ){
*spscr++=(*sync+16);sync++;
*spscr++=(*sync+16);sync++;
*spscr++=*sync++;
*spscr++=*sync++;
}
sp_off(sppl,127);
}
if( vwait==0 ){ vonWait(); }
}
TASK *sortbuf[256][MAX_ETASK+1];
TASK **sortline[256];
/*
(今のところ敵機のみ)Y座標表示ソート付きSyncMan
プレイヤーの優先順位を最下位に
*/
int SyncManY()
{
static FIX32 cnt=0;
short d,sppl;
{//スプライト
short tn,sn,an,px,py,pat;
short sx,sy;
TASK *t; //通常タスク
ESTASK *e; //敵弾
PSTASK *m; //
SPINFO *s;
SPLINK *l;
sppl=0;
//敵機のソート
for( tn=0; tn<256; tn++ ){
sortbuf[tn][0]=0;
sortline[tn]=sortbuf[tn];
}
for( tn=0;tn<MAX_ETASK;tn++ ){
t=&ETask[tn];
if( t->func_addr==NULL ){ continue; }
s=t->disp0_addr;
if( s==NULL ){ continue; }
py=*(short *)&(t->disp0_y);
if( py>=0 && py<255 ){
*sortline[py]++=t;
*sortline[py]=0;
}
}
//敵機
for( sy=255; sy>=0; sy-- ){ ; for( sx=0; sx<32; sx++ ){
t=sortbuf[sy][sx];
if( t==0 ){ break; }
// if( t->func_addr==NULL ){ continue; }
s=t->disp0_addr;
if( s==NULL ){ continue; }
//以下、表示
an=t->disp0_anim;
px=*(short *)&(t->disp0_x);
py=*(short *)&(t->disp0_y);
for( sn=0;sn<s->anim_info[an]->chips;sn++ ){
/*
px+=s->anim_info[an]->splink[sn].ox;
py+=s->anim_info[an]->splink[sn].oy;
pat=s->anim_info[an]->splink[sn].patnum;
*/
l=&(s->anim_info[an]->splink[sn]);
px+=l->ox;
py+=l->oy;
pat=l->patnum;
if( t->disp0_palet!=0 ){
pat&=0xf0ff;
pat=pat|(t->disp0_palet<<8);
}
X6sp_set(sppl,px,py,pat,3);
sppl++;
}
}}
//アイテム等
for( tn=0;tn<MAX_ITASK;tn++ ){
t=&ITask[tn];
if( t->func_addr==NULL ){ continue; }
// if( t->delay_timer>0 ){ continue; }
s=t->disp0_addr;
if( s==NULL ){ continue; }
//以下、表示
an=t->disp0_anim;
px=*(short *)&(t->disp0_x);
py=*(short *)&(t->disp0_y);
for( sn=0;sn<s->anim_info[t->disp0_anim]->chips;sn++ ){
l=&(s->anim_info[t->disp0_anim]->splink[sn]);
px+=l->ox;
py+=l->oy;
pat=l->patnum;
if( t->disp0_palet!=0 ){
pat&=0xf0ff;
pat=pat|(t->disp0_palet<<8);
}
X6sp_set(sppl,px,py,pat,3);
sppl++;
}
}
//敵弾用(1チップ限定)
for( tn=0;tn<MAX_ESTASK;tn++ ){
e=&ESTask[tn];
if( e->func_addr==NULL ){ continue; }
// if( e->delay_timer>0 ){ continue; }
s=e->disp0_addr;
if( s==NULL ){ continue; }
//以下、表示
an=e->disp0_anim;
px=*(short *)&(e->disp0_x);
py=*(short *)&(e->disp0_y);
sn=0;
l=&(s->anim_info[an]->splink[sn]);
px+=l->ox;
py+=l->oy;
pat=l->patnum;
if( t->disp0_palet!=0 ){
pat&=0xf0ff;
pat=pat|(t->disp0_palet<<8);
}
X6sp_set(sppl,px,py,pat,3);
sppl++;
}
//自機弾用(1チップ限定)
for( tn=0;tn<MAX_PSTASK;tn++ ){
m=&PSTask[tn];
if( m->func_addr==NULL ){ continue; }
// if( m->delay_timer>0 ){ continue; }
s=m->disp0_addr;
if( s==NULL ){ continue; }
//以下、表示
an=m->disp0_anim;
px=*(short *)&(m->disp0_x);
py=*(short *)&(m->disp0_y);
sn=0;
l=&(s->anim_info[an]->splink[sn]);
px+=l->ox;
py+=l->oy;
pat=l->patnum;
if( t->disp0_palet!=0 ){
pat&=0xf0ff;
pat=pat|(t->disp0_palet<<8);
}
X6sp_set(sppl,px,py,pat,3);
sppl++;
}
//プレイヤー
for( tn=0;tn<=1;tn++ ){
t=&PTask[tn];
if( t->func_addr==NULL ){ continue; }
// if( t->delay_timer>0 ){ continue; }
s=t->disp0_addr;
if( s==NULL ){ continue; }
//以下、表示
an=t->disp0_anim;
px=*(short *)&(t->disp0_x);
py=*(short *)&(t->disp0_y);
for( sn=0;sn<s->anim_info[an]->chips;sn++ ){
l=&(s->anim_info[an]->splink[sn]);
px+=l->ox;
py+=l->oy;
pat=l->patnum;
if( t->disp0_palet!=0 ){
pat&=0xf0ff;
pat=pat|(t->disp0_palet<<8);
}
X6sp_set(sppl,px,py,pat,3);
sppl++;
}
}
}
if( vwait==0 ){ voffWait(); }
//スクロール
{
int pn;
unsigned short *spscr=0xEB0000,
*sync=X6sync_buf;
for( pn=0;pn<min(sppl,128);pn++ ){
*spscr++=(*sync+16);sync++;
*spscr++=(*sync+16);sync++;
*spscr++=*sync++;
*spscr++=*sync++;
}
sp_off(sppl,127);
}
if( vwait==0 ){ vonWait(); }
}
/*
sにはかならず32768byteのバッファを指定
*/
int SetX6Pcgbuf(addr)
unsigned short *addr;
{
unsigned short *s,*d=0xEB8000;
int cnt;
s=addr;
for( cnt=0;cnt<(32768/2);cnt++ ){
*d++=*s++;
}
return(0);
}
int SetX6Palbuf(addr)
unsigned short *addr;
{
unsigned short *s,*d=0xE82220;
int cnt;
s=addr;
for( cnt=0;cnt<240;cnt++ ){
*d++=*s++;
}
// tbg_newpalet();
return(0);
}
//----------------------------------------------------------------------TaskMan()
/*@@ 重要 @@
現在のTaskManの仕様変更、
・確保(Alloc)時には、ワークアドレスを返すだけ
・解放(Free)時に、タスクワークを0クリア
*/
/*
*/
int TaskMan__allfreeFlag; //1=allTaskFreeを実行した
int TaskMan()
{
short tn;
TASK *t;
ESTASK *es;
PSTASK *ps;
int (*func)(),ot;
/* 管理タスク */
/*
自分のなかでAllTaskFreeし、自分を再登録すると
同じ(昔自分がいた)ワークエリアにもう一度自分を作ることがある。
すると、t->func_addrは一見、何事もなかったような状態になる
(→MTaskが1つだけの時、AllTaskFreeした直後MTaskを確保した時なんかになる。
しかし、一回AllTaskFreeしているので、->local_counterは0になる)
@@これおかしい。というかタイミングがあわない場合もある。
*/
for( tn=0;tn<MAX_MTASK;tn++ ){
t=&MTask[tn];
if( t->func_addr==NULL ){ continue; }
if( t->delay_timer>0 ){ t->delay_timer--; continue; }
func=t->func_addr;
ot=t->local_counter;
func(t);
if( t->func_addr ){ //自分のなかでTaskFreeしかたチェック
if( ot!=t->local_counter ){
t->local_counter=0; //念のため
}
else{
t->local_counter++;
}
}
}
TaskMan__allfreeFlag=0;
/* プレーヤータスク */
for( tn=0;tn<=1;tn++ ){
t=&PTask[tn];
if( t->func_addr==NULL ){ continue; }
if( t->delay_timer>0 ){
t->delay_timer--;
continue;
}
//以下、AllocしたTASKを走らせる
func=t->func_addr;
func(t);
if( t->func_addr ){ t->local_counter++; }
}
/* 敵タスク */
for( tn=0;tn<MAX_ETASK;tn++ ){
t=&ETask[tn];
if( t->func_addr==NULL ){ continue; }
if( t->delay_timer>0 ){ t->delay_timer--; continue; }
func=t->func_addr;
func(t);
if( t->func_addr ){ //func(t)でETaskFreeした場合を考慮
t->local_counter++;
}
}
/* アイテム等タスク */
for( tn=0;tn<MAX_ITASK;tn++ ){
t=&ITask[tn];
if( t->func_addr==NULL ){ continue; }
if( t->delay_timer>0 ){ t->delay_timer--; continue; }
func=t->func_addr;
func(t);
if( t->func_addr ){ t->local_counter++; }
}
/* 敵弾 */
for( tn=0;tn<MAX_ESTASK;tn++ ){
es=&ESTask[tn];
if( es->func_addr==NULL ){ continue; }
if( es->delay_timer>0 ){ es->delay_timer--; continue; }
func=es->func_addr;
func(es);
}
/* 自機弾 */
for( tn=0;tn<MAX_PSTASK;tn++ ){
ps=&PSTask[tn];
if( ps->func_addr==NULL ){ continue; }
func=ps->func_addr;
func(ps);
}
// IdleTask(); //@@いらんくらい
return( (gameStep==STEP_EXIT)?-1:0 );
}
/*
*/
int AllTaskFree()
{
short ct;
PTask[0]=nTask; //プレーヤー
PTask[1]=nTask;
for( ct=0;ct<MAX_ETASK;ct++ ){ ETask[ct]=nTask; }//敵タスク
for( ct=0;ct<MAX_MTASK;ct++ ){ MTask[ct]=nTask; }//管理タスク
for( ct=0;ct<MAX_ITASK;ct++ ){ ITask[ct]=nTask; }//アイテムタスク
for( ct=0;ct<MAX_ESTASK;ct++ ){ ESTask[ct]=nesTask; }//敵弾
for( ct=0;ct<MAX_PSTASK;ct++ ){ PSTask[ct]=npsTask; }//自機弾
TaskMan__allfreeFlag=1;
return(0);
}
/*
*/
int AllETaskFree()
{
short ct;
for( ct=0;ct<MAX_ETASK;ct++ ){ ETask[ct]=nTask; }//敵タスク
return(0);
}
int AllESTaskFree()
{
short ct;
for( ct=0;ct<MAX_ESTASK;ct++ ){ ESTask[ct]=nesTask; }//敵弾
return(0);
}
/*
プレーヤータスク登録
RES:タスクワークアドレス、0の時確保失敗
*/
int *PTaskAlloc(pn)
int pn; //0or1:プレーヤー番号
{
int *res=0;
if( PTask[pn].func_addr==0 ){
res=&PTask[pn];
}
return(res);
}
/*
RES:0以外、登録したタスクワーク番号
*/
TASK *MTaskAlloc()
{
short ct;
TASK *t;
for( ct=0;ct<MAX_MTASK;ct++ ){
t=&MTask[ct];
if( t->func_addr==NULL ){ //空タスク発見
goto quick_exit;
}
}
t=0;
quick_exit:
return(t);
}
/*
RES:0以外、確保可能なタスクアドレス
*/
TASK *ETaskAlloc()
{
short ct;
TASK *t;
for( ct=0;ct<MAX_ETASK;ct++ ){
t=&ETask[ct];
if( t->func_addr==NULL ){ //空タスク発見
goto quick_exit;
}
}
t=NULL;
quick_exit:
return(t);
}
/*
RES:0以外、登録したタスクワーク番号
*/
TASK *ITaskAlloc()
{
short ct;
TASK *t;
for( ct=0;ct<MAX_ITASK;ct++ ){
t=&ITask[ct];
if( t->func_addr==NULL ){ //空タスク発見
goto quick_exit;
}
}
t=0;
quick_exit:
return(t);
}
/*
RES:0以外、排除したタスクワーク番号
*/
int MTaskFree(task)
TASK *task;
{
*task=nTask;
return(0);
}
/*
RES:0以外、排除したタスクワーク番号
*/
int ETaskFree(task)
TASK *task;
{
*task=nTask;
return(0);
}
/*
RES:0以外、排除したタスクワーク番号
*/
int ITaskFree(task)
TASK *task;
{
*task=nTask;
return(0);
}
/*
敵弾用:RES:0以外、登録したタスクワーク番号
*/
ESTASK *ESTaskAlloc(task)
ESTASK *task;
{
short ct;
ESTASK *t;
for( ct=0;ct<MAX_ESTASK;ct++ ){
t=&ESTask[ct];
if( t->func_addr==NULL ){
goto quick_exit;
}
}
t=0;
quick_exit:
return(t);
}
/*
敵弾:RES:0以外、排除したタスクワーク番号
*/
int ESTaskFree(task)
ESTASK *task;
{
*task=nesTask;
return(0);
}
/*
自機弾弾用:RES:0以外、登録したタスクワーク番号
*/
PSTASK *PSTaskAlloc()
{
short ct;
PSTASK *t;
for( ct=0;ct<MAX_PSTASK;ct++ ){
t=&PSTask[ct];
if( t->func_addr==NULL ){
goto quick_exit;
}
}
t=0;
quick_exit:
return(t);
}
/*
自機弾:RES:0以外、排除したタスクワーク番号
*/
int PSTaskFree(task)
PSTASK *task;
{
*task=npsTask;
return(0);
}
////////////////////////////////////////////////////////////////////////////////
// hitchk.c であったトコロ
////////////////////////////////////////////////////////////////////////////////
/*
あたり判定(プレイヤーは1のみ)
*/
/*
単純判定(うごくだけまし)
*/
int HitchkMan0()
{
TASK *et,*pt;
PSTASK *ps;
ESTASK *es;
short en,sn;
/*
自機弾(点)vs 敵機(クケー)
*/
for( en=0;en<MAX_ETASK;en++ ){
et=&ETask[en];
if( et->func_addr==NULL ){ continue; }
for( sn=0;sn<MAX_PSTASK;sn++ ){
ps=&PSTask[sn];
if( ps->func_addr==NULL ){ continue; }
if(
(et->disp0_x+(et->hit_x0<<16) <= ps->disp0_x) &&
(ps->disp0_x <= et->disp0_x+(et->hit_x1<<16)) &&
(et->disp0_y+(et->hit_y0<<16) <= ps->disp0_y) &&
(ps->disp0_y <= et->disp0_y+(et->hit_y1<<16))
){
et->task_command=TC_HIT_SHOT; //やられコード埋め込み
ps->task_command=TC_HIT_ENEMY;
et->hit_addr=(int *)ps;
// ps->hit_addr=(int *)et;
}
}
}
/*
自機(クケー) vs 敵弾(点)
*/
pt=&PTask[0];
pt->hit_addr=0; //自機の対あたりクリアわすれるな
for( sn=0;sn<MAX_ESTASK;sn++ ){
es=&ESTask[sn];
if( es->func_addr==NULL ){ continue; }
if(
(pt->disp0_x+(pt->hit_x0<<16) <= es->disp0_x) &&
(es->disp0_x <= pt->disp0_x+(pt->hit_x1<<16)) &&
(pt->disp0_y+(pt->hit_y0<<16) <= es->disp0_y) &&
(es->disp0_y <= pt->disp0_y+(pt->hit_y1<<16))
){
pt->task_command=TC_HIT_SHOT; //やられ
es->task_command=TC_HIT_PLAYER;
pt->hit_addr=(int *)es;
// es->hit_addr=(int *)es; //esにhit_addrは用意しない
}
}
/*
自機(クケー) vs 敵(クケー)
*/
pt=&PTask[0];
if( pt->func_addr==NULL ){ goto end_ptet; }
if( *(int *)(&(pt->hit_x0))==0 ){ goto end_ptet; }
for( en=0;en<MAX_ETASK;en++ ){
et=&ETask[en];
if( et->func_addr==NULL ){ continue; }
if( pt->disp0_x+(pt->hit_x0<<16) > et->disp0_x+(et->hit_x1<<16) ){ continue; }
if( pt->disp0_x+(pt->hit_x1<<16) < et->disp0_x+(et->hit_x0<<16) ){ continue; }
if( pt->disp0_y+(pt->hit_y0<<16) > et->disp0_y+(et->hit_y1<<16) ){ continue; }
if( pt->disp0_y+(pt->hit_y1<<16) < et->disp0_y+(et->hit_y0<<16) ){ continue; }
pt->task_command=TC_HIT_ENEMY; //やられ
et->task_command=TC_HIT_PLAYER;
pt->hit_addr=(int *)et;
et->hit_addr=(int *)pt;
}
end_ptet:;
/*
自機(クケー) vsアイテム(クケー)
*/
pt=&PTask[0];
if( pt->func_addr==NULL ){ goto end_ptit; }
if( *(int *)(&(pt->hit_x0))==0 ){ goto end_ptit; }
for( en=0;en<MAX_ITASK;en++ ){
et=&ITask[en];
if( et->func_addr==NULL ){ continue; }
if( *(int *)(&(et->hit_x0))==0 ){ continue; }
if( pt->disp0_x+(pt->hit_x0<<16) > et->disp0_x+(et->hit_x1<<16) ){ continue; }
if( pt->disp0_x+(pt->hit_x1<<16) < et->disp0_x+(et->hit_x0<<16) ){ continue; }
if( pt->disp0_y+(pt->hit_y0<<16) > et->disp0_y+(et->hit_y1<<16) ){ continue; }
if( pt->disp0_y+(pt->hit_y1<<16) < et->disp0_y+(et->hit_y0<<16) ){ continue; }
pt->task_command=TC_HIT_ITEM; //ゲット
et->task_command=TC_HIT_PLAYER;
pt->hit_addr=(int *)et;
et->hit_addr=(int *)pt;
}
end_ptit:;
return(0);
}
////////////////////////////////////////////////////////////////////////////////
// sound.c であったトコロ
////////////////////////////////////////////////////////////////////////////////
/*
sound.c
*/
/*
→sound000.tbl
*/
/*
基本的に音にまつわるあれこれに関する外部からの要求は、「SOUND_CALL」にのみ
対応する。
mod=0 音関係の初期設定(ファイル読み込みを含む)
bit0~7 音番号
bit8=0 PCM
bit8=1 ZMD
bit12=1 制御関係
*/
extern int PCMADDR[],PCMLEN[];
extern char *ZMDINFO[];
int SOUND_CALL(mod)
int mod;
{
int res=0;
static int omod,ommod;
//goto quick_exit;
if( mod==-1 ){ //1つ前に鳴らした番号リクエスト
res=omod;
goto quick_exit;
}
if( mod==-2 ){ //1つ前に鳴らしたBGM番号リクエスト
res=ommod;
goto quick_exit;
}
if( mod==0 ){
/*
音関係の初期設定
*/
SOUND_CALL(0x0101); //BGM_INIT
goto quick_exit;
}
if( mod&0x800 ){
//制御
m_stop(0,0, 0,0, 0,0, 0,0, 0,0);
}
else if( mod&0x100 ){
//ZMD
int num;
ommod=mod;
num=mod&0xff;
zmd_play(ZMDINFO[num]);
///**/ cls();printf(ZMDINFO[num]);getch();
}
else{
//PCM
unsigned char *adr;
int len,pmod=0x0403;
adr=PCMADDR[mod];
len=PCMLEN[mod];
ADPCMOUT(adr,pmod,len);
}
omod=mod;
quick_exit:
return(res);
}
////////////////////////////////////////////////////////////////////////////////
// vec10.cだった
////////////////////////////////////////////////////////////////////////////////
/*------------------------------------------------------------------------------*/
/*
単位ベクトルテーブル
座標系
┌─→+x において、方向番号0~255は、以下に示すよう
│
↓
+y
192
128┌─→+x0
│
↓ (1,0)を開始点とした逆時計周りでカウントアップ
+y
64
*/
typedef struct {
FIX32 ivx;
FIX32 ivy;
} IVECTOR; //単位ベクトル(1,15,16)
/*
(sx,sy)からみて(tx,ty)はどの方向に位置しているかを高速サーチする。
分解能は256。(←経験則的値)これでだいたい足りるものだ
X68での使用での現実的な精巧サーチを実現するには2048段階必要
(画面端1ドットから画面端1ドットに当てることができる)
オフセット座標からのテーブルでもかまわない(むしろそちらの方が速い)が、
データサイズがやたらでかくなる。って、なんか、みみっちい。
*/
unsigned short TAN32TBL[]={
0x0000,0x0648,0x0C91,0x12DF,0x1933,0x1F8E,0x25F4,0x2C65,
0x32E5,0x3974,0x4017,0x46CE,0x4D9D,0x5486,0x5B8C,0x62B1,
0x69FA,0x7169,0x7902,0x80C8,0x88C0,0x90EF,0x9958,0xA201,
0xAAF1,0xB42D,0xBDBB,0xC7A5,0xD1F1,0xDCAA,0xE7D9,0xF38B
};
//方向番号を返す
short Search256(sx,sy,tx,ty)
short sx,sy; //始点
short tx,ty; //終点
{
short dx,dy; //distance
short rev_flag=0; // 0000 0XHV
//
unsigned short tandy; //tan - dy
short phy=0; //角度番号
dx=tx-sx;
dy=ty-sy;
if( dx==0 ){
phy=( (ty-sy)>=0 )?64:192;
goto quick_exit;
}
if( dy==0 ){
phy=( (tx-sx)>=0 )?0:128;
goto quick_exit;
}
if( dy<0 ){
dy=-dy;
rev_flag|=0x01;
}
if( dx<0 ){
dx=-dx;
rev_flag|=0x02;
}
if( dy>dx ){
int tmp;
tmp=dy;
dy=dx;
dx=tmp;
rev_flag|=0x04;
}
//この時点でdx,dy共に+の値でdx>dyが保証される
if( dx==dy ){
phy=31;
goto endSch32;
}
tandy=(unsigned short)(((int)dy<<16)/dx);
if( tandy<TAN32TBL[16] ){ //N.16=0.414213
//N=0-15
if( tandy<TAN32TBL[8] ){ //N.8=0.198912
//N=0-7
if( tandy<TAN32TBL[4] ){ //N.4
//N=0-3
if( tandy<TAN32TBL[2] ){ //N.2
//N=0-1
phy=( tandy<TAN32TBL[1] )?0:1; //N.0or1
}
else{
//N=2-3
phy=( tandy<TAN32TBL[3] )?0:1; //N.2or3
}
}
else{
//N=4-7
if( tandy<TAN32TBL[6] ){
//N=4-5
phy=( tandy<TAN32TBL[5] )?4:5;
}
else{
//N=6-7
phy=( tandy<TAN32TBL[7] )?6:7;
}
}
}
else{
//N=8-15
if( tandy<TAN32TBL[12] ){
//N=8-11
if( tandy<TAN32TBL[10] ){
//N=8-9
phy=( tandy<TAN32TBL[9] )?8:9;
}
else{
//N=10-11
phy=( tandy<TAN32TBL[11] )?10:11;
}
}
else{
//N=12-15
if( tandy<TAN32TBL[14] ){
//12-13
phy=( tandy<TAN32TBL[13] )?12:13;
}
else{
//14-15
phy=( tandy<TAN32TBL[15] )?14:15;
}
}
}
}
else{
//N=16-31
if( tandy<TAN32TBL[24] ){
//N=16-23
if( tandy<TAN32TBL[20] ){
//N=16-19
if( tandy<TAN32TBL[18] ){
//N=16-17
phy=( tandy<TAN32TBL[17] )?16:17;
}
else{
//N=18-19
phy=( tandy<TAN32TBL[19] )?18:19;
}
}
else{
//N20-23
if( tandy<TAN32TBL[22] ){
//N=20-21
phy=( tandy<TAN32TBL[21] )?20:21;
}
else{
//N=22-23
phy=( tandy<TAN32TBL[23] )?22:23;
}
}
}
else{
//N=24-31
if( tandy<TAN32TBL[28] ){
//N=24-27
if( tandy<TAN32TBL[26] ){
//N=24-25
phy=( tandy<TAN32TBL[25] )?24:25;
}
else{
//N=26-27
phy=( tandy<TAN32TBL[27] )?26:27;
}
}
else{
//N=28-31
if( tandy<TAN32TBL[30] ){
//N=28-29
phy=( tandy<TAN32TBL[29] )?28:29;
}
else{
//N=30-31
phy=( tandy<TAN32TBL[31] )?30:31;
}
}
}
}
/*
↑このへんはループで綺麗に書いたいいかもしれないが、
なんとなく、全部展開しておく。気分の問題
*/
endSch32:
if( rev_flag&0x04 ){ //X-flag
phy=63-phy;
}
if( rev_flag&0x02 ){ //H-flag
phy=127-phy;
}
if( rev_flag&0x01 ){ //V-flag
phy=255-phy;
}
quick_exit:
return(phy);
}
/*
256方向からジョイスティック8方向へ変換
*/
short D256toJ8(sdir)
short sdir;
{
short jdir=0;
if( 0<=sdir && sdir<16 ){ jdir=6; }
else if( 16<=sdir && sdir<48 ){ jdir=3; }
else if( 48<=sdir && sdir<80 ){ jdir=2; }
else if( 80<=sdir && sdir<112 ){ jdir=1; }
else if( 112<=sdir && sdir<144 ){ jdir=4; }
else if( 144<=sdir && sdir<176 ){ jdir=7; }
else if( 176<=sdir && sdir<208 ){ jdir=8; }
else if( 208<=sdir && sdir<240 ){ jdir=9; }
else if( 240<=sdir && sdir<256 ){ jdir=6; }
return(jdir);
}
/*
ジョイスティック8方向を返す
使い方はSearch256とおなじ
*/
short SearchJ8(sx,sy,tx,ty)
short sx,sy; //始点
short tx,ty; //終点
{
short sdir,jdir;
sdir=Search256(sx,sy,tx,ty);
jdir=D256toJ8(sdir);
return(jdir);
}
/*
Y軸(x=0)との衝突
┃ ┃
┃@┃
┃ ┃
*/
short dir256_reflect_ay(in)
short in;
{
short out;
if( in==0 ){ out=128; }
else if( in==64 ){ out=192; } //ありえないけど
else if( in==128 ){ out=0; }
else if( in==192 ){ out=64; } //こいつもありえないけど
//
else if( 1<=in && in<= 63 ){ out=128-in; } //3
else if( 65<=in && in<=127 ){ out=128-in; } //1
else if( 129<=in && in<=191 ){ out=256-(in-128); } //7
else if( 193<=in && in<=255 ){ out=128+(256-in); } //9
return(out);
}
/*
X軸(y=0)との衝突
━━━
@
━━━
*/
short dir256_reflect_ax(in)
short in;
{
short out;
if( in==0 ){ out=128; } //ありえないけど
else if( in==64 ){ out=192; }
else if( in==128 ){ out=0; } //こいつもありえないけど
else if( in==192 ){ out=64; }
//
else if( 1<=in && in<= 63 ){ out=256-in; }
else if( 65<=in && in<=127 ){ out=128+(128-in); }
else if( 129<=in && in<=191 ){ out= 64+(191-in); }
else if( 193<=in && in<=255 ){ out= 64-(in-192); }
return(out);
}
////////////////////////////////////////////////////////////////////////////////
// よく使われるタスク
////////////////////////////////////////////////////////////////////////////////
int ANIMONLY_JOB(t)
TASK *t;
{
SPINFO *s;
s=t->disp0_addr;
t->disp0_anim++;
if( t->disp0_anim>=s->max_anim ){
ETaskFree(t);
}
quick_exit:;
return(0);
}
int LOOPANIM_JOB(t)
TASK *t;
{
SPINFO *s;
s=t->disp0_addr;
t->disp0_anim++;
if( t->disp0_anim>=s->max_anim ){
t->disp0_anim=0;
}
quick_exit:;
return(0);
}
int NOP_JOB(t)
TASK *t;
{
return(0);
}
/*
1ドット自機弾専用タスク
*/
int PLAYERSHT_JOB(t)
PSTASK *t;
{
SPINFO *s;
s=t->disp0_addr;
t->disp0_x+=t->disp0_vx; //弾移動
t->disp0_y+=t->disp0_vy;
if( //画面アウトチェック
( t->disp0_x<0 ) || ( t->disp0_y<0 ) ||
( t->disp0_x>(256<<16) ) || ( t->disp0_y>(256<<16) )
){
PSTaskFree(t);
goto quick_exit;
}
quick_exit:
return(0);
}
/*
1ドット敵弾専用タスク
*/
int ENEMYSHT_JOB(t)
ESTASK *t;
{
SPINFO *s;
s=t->disp0_addr;
t->disp0_x+=t->disp0_vx; //敵弾移動
t->disp0_y+=t->disp0_vy;
if(
( t->disp0_x<0 ) || ( t->disp0_y<0 ) ||
( t->disp0_x>(256<<16) ) || ( t->disp0_y>(256<<16) )
){
ESTaskFree(t);
goto quick_exit;
}
t->disp0_anim++; //アニメ更新
if( t->disp0_anim>=s->max_anim ){
t->disp0_anim=0;
}
quick_exit:
return(0);
}
/* [ EOF ] */